package cate.game.pvp.championrace.timer;

import cate.game.event.championrace.ChampionRaceTimerEvent;
import cate.game.framework.timer.FIFOTimerTask;
import cate.game.pvp.championrace.data.ChampionRaceSpec;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.google.common.base.MoreObjects;
import easy.java.dev.note.NoteField;
import easy.java.time.DateTool;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;

import java.util.Objects;
import java.util.StringJoiner;
import java.util.function.Consumer;
import java.util.function.Function;

@ToString(exclude = {"settingsConsumer", "settingsFunction"})
public class ChampionRaceTimerTask extends FIFOTimerTask {
    @NoteField(value = "接受一个setting 返回一个布尔值")
    private final Setting setting;

    @JsonIgnore
    private final Consumer<Setting> settingConsumer;
    private final Function<Setting, Boolean> settingHandler;

    public ChampionRaceTimerTask(Setting setting,
                                 Consumer<Setting> settingConsumer,
                                 Function<Setting, Boolean> settingHandler) {
        super(setting.triggerTimeMs);
        this.setting = setting;
        this.settingConsumer = settingConsumer;
        this.settingHandler = MoreObjects.firstNonNull(settingHandler, s -> true);
    }

    @NoArgsConstructor
    @Data
    public static class Setting {

        private ChampionRaceSpec spec;

        private long triggerTimeMs;
        private ChampionRaceTimerEvent.EventType eventType = ChampionRaceTimerEvent.EventType.OPEN;

        public static Setting of(long triggerTimeMs, ChampionRaceTimerEvent.EventType eventType, ChampionRaceSpec spec) {
            Setting settings = new Setting();
            settings.setSpec(spec);
            settings.setTriggerTimeMs(triggerTimeMs);
            settings.setEventType(eventType);
            return settings;
        }

        @Override
        public String toString() {
            return new StringJoiner(", ", Setting.class.getSimpleName() + "[", "]")
                    .add("spec=" + spec)
                    .add("triggerTimeMs=" + DateTool.instance().format(triggerTimeMs))
                    .add("eventType=" + eventType)
                    .toString();
        }
    }

    @Override
    public void run() {
        boolean apply = this.settingHandler.apply(this.setting);
        if (apply && !isDone()) {
            setDone(true);
            if (Objects.nonNull(this.settingConsumer)) {
                settingConsumer.accept(setting);
            }
        }
    }
}
